package cn.yitun.chat.yitunserverimapicore.business.group.service.impl;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.Info;
import cn.yitun.chat.yituncommonutil.YitunMapUtil;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.group.GroupInviteApplyDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.group.GroupJoinApplyDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.group.GroupInviteApplyVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.group.GroupJoinApplyVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.group.GroupMemberVo;
import cn.yitun.chat.yitunservercommonlib.enums.groupChat.GroupMemberPositionEnums;
import cn.yitun.chat.yitunservercommonlib.util.R;
import cn.yitun.chat.yitunservercommonlib.util.codec.IdGen;
import cn.yitun.chat.yitunserverimapicore.business.group.service.GroupManageService;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupInviteApplyDao;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupJoinApplyDao;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupMemberDao;
import cn.yitun.chat.yitunserverimbase.dao.group.GroupRelationDao;
import cn.yitun.chat.yitunserverimcore.general.main.biz.group.manager.GroupMemberManager;
import cn.yitun.chat.yitunserverimcore.general.main.push.group.GroupBusinessPush;
import cn.yitun.chat.yitunserverimcore.general.main.push.group.GroupMemberPush;
import cn.yitun.chat.yitunserverimcore.general.main.push.group.GroupRelationPush;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * Date 2019-01-23 22:01:34<br>
 * Description
 * 
 * @author yitun
 * @since 1.0.0
 */
@Service
@Transactional
public class GroupManageServiceImpl implements GroupManageService {

	@Resource
	private GroupJoinApplyDao groupJoinApplyDao;
	@Resource
	private GroupInviteApplyDao groupInviteApplyDao;
	@Resource
	private GroupMemberDao groupMemberDAO;
	@Resource
	private GroupRelationDao groupRelationDAO;
	@Resource
	private GroupMemberManager groupMemberManager;
	@Resource
	private GroupMemberPush groupMemberPush;
	@Resource
	private GroupBusinessPush groupBusinessPush;
	@Resource
	private GroupRelationPush groupRelationPush;

	/**
	 * 
	 * Date 2019-01-24 22:08:14<br>
	 * Description 管理员或者群主获取申请加入群的请求列表
	 *
	 * @author yitun
	 * @param userId
	 * @return
	 * @since 1.0.0
	 */
	public List<GroupJoinApplyVo> getJoinRequestListByUserId(Long userId, int pageNo, int pageSize) {
		PageHelper.startPage(pageNo, pageSize);
		List<GroupJoinApplyVo> list = groupJoinApplyDao.getJoinRequestListByUserId(userId);
		return list;
	}

	public List<GroupJoinApplyVo> queryJoinRequestList(GroupJoinApplyDto query) {
		List<GroupJoinApplyVo> list = groupJoinApplyDao.queryJoinRequestList(query);
		return list;
	}
	/**
	 *
	 * Date 2019-01-26 09:34:41<br>
	 * Description
	 * 群主或管理员 获取请求入群 计数
	 * @author yitun
	 * @param query
	 * @return
	 * @since 1.0.0
	 */
	public int countJoinRequest(GroupJoinApplyDto query) {
		return groupJoinApplyDao.countJoinRequest(query);
	}

	/**
	 *
	 * Date 2019-01-26 09:34:41<br>
	 * Description 管理员或者群主获取审批邀请的用户
	 *
	 * @author yitun
	 * @param query
	 * @return
	 * @since 1.0.0
	 */
	public List<GroupInviteApplyVo> queryInviteRequestList(GroupInviteApplyDto query) {
		query.setOtherConditions("AND ( a.inviter_user_position = 1 OR a.inviter_user_position = 2 )");
		List<GroupInviteApplyVo> list = groupInviteApplyDao.listVO(YitunMapUtil.java2Map(query, false));
		return list;
	}

	/**
	 * 邀请入群 计数
	 * @param query
	 * @return
	 */
	@Override
	public int countInviteRequestList(GroupInviteApplyDto query) {
		return groupInviteApplyDao.count(YitunMapUtil.java2Map(query, false));
	}

	/**
	 * 
	 * Date 2019-01-26 14:54:46<br>
	 * Description 转让群主
	 * 
	 * @author yitun
	 * @param groupId
	 * @param oldOwnerUserId
	 * @param newOwnerUserId
	 * @return
	 * @since 1.0.0
	 */
	public Info changeGroupOwner(Long groupId, Long oldOwnerUserId, Long newOwnerUserId) {
		Info info = new Info();
		boolean isOwner = groupMemberManager.isOwner(groupId, oldOwnerUserId);
		// 是群主才能转让
		if (isOwner) {
			// 原群主设为普通成员
			groupMemberDAO.updatePosition(groupId, oldOwnerUserId, GroupMemberPositionEnums.POSITION_NORMAL.getType());
			// 设置新群主
			groupMemberDAO.updatePosition(groupId, newOwnerUserId, GroupMemberPositionEnums.POSITION_OWNER.getType());

			// TODO推送群主变化消息
			List<Long> userIds = new ArrayList<>();
			List<GroupMemberVo> list = groupMemberDAO.listVO(
					R.param("groupId", groupId));
			for (GroupMemberVo m : list) {
				userIds.add(m.getUserId());
			}
			groupMemberPush.pushUpdatePosition(groupId, oldOwnerUserId, GroupMemberPositionEnums.POSITION_NORMAL.getType(), userIds);
			groupMemberPush.pushUpdatePosition(groupId, newOwnerUserId, GroupMemberPositionEnums.POSITION_OWNER.getType(), userIds);
		} else {
			info.addWarning(ExceptionEnum.SOCK_GROUP_MEMBER_NO_PERMISSION);
		}
		return info;
	}

	/**
	 * 
	 * Date 2019-01-26 15:01:20<br>
	 * Description 解散群
	 * 
	 * @author yitun
	 * @param groupId
	 * @param ownerUserId
	 * @return
	 * @since 1.0.0
	 */
	@Transactional(rollbackFor = Exception.class)
	public Info disbandGroup(Long groupId, Long ownerUserId) {
		Info info = new Info();
		boolean isOwner = groupMemberManager.isOwner(groupId, ownerUserId);
		// 是群主才能解散群
		if (isOwner) {
			List<Long> userIds = new ArrayList<>();
			List<GroupMemberVo> list = groupMemberDAO.listVO(
			        R.param("groupId", groupId));
			for (GroupMemberVo m : list) {
				userIds.add(m.getUserId());
			}
			// 删除群主以外的其他成员
			groupMemberDAO.deleteOutUserIdByGroupId(groupId, ownerUserId);

			groupRelationDAO.deleteOutUserIdByGroupId(groupId, ownerUserId);
			// TODO推送解散群消息 userIds
			groupBusinessPush.pushDisband(IdGen.getNumber(), groupId, ownerUserId, ownerUserId);

			userIds.remove(ownerUserId);
			groupRelationPush.pushDelete(IdGen.getNumber(), groupId, userIds);
		} else {
			info.addWarning(ExceptionEnum.SOCK_GROUP_MEMBER_NO_PERMISSION);
		}
		return info;
	}
}
